#! /usr/bin/python
# -*- coding: cp1250 -*-

import string
import re
import glob
import pepe.p_txt.bigtxt as bt
from pepe.lambdas import space_fill

n = '\x0D\x0A'

def longest_file_line(f):
    longest_line = 0
    for line in bt.lines(f):
        if len(line) > longest_line:
            longest_line = len(line)
    return longest_line

def cut_by_index(data, indexes):
    """    Cut data to columns using based on suplied indexes.
    """
    cols = []
    for i,v in enumerate(indexes):
        if v <> 0:
            v_start = indexes[i-1]
            v_end = v
            col = string.strip(data[v_start:v_end])
            cols.append(col)
    return cols

class FileColumnsInfo:
    """    Find empty columns - containing only spaces.
    
    Only find out indexes where columns are expected to be.

    That information (indexes list) can be then reused 
    (to minimalize need to run routines multiple times over big files)
    and customized when using FilesColumnsCut.
    
    2010-09-12 vp rewrite of previous library
    """
    def __init__(self):
        """ """
        pass

    def examine(self, filemask=''):
        """ """
        fc_indexes = {} # files column indexes        

        if filemask == '': 
            print "Error: File mask not defined."
        else:
            for f in sorted(glob.glob(filemask)):
                fname = string.split(f, '.')[0] 
                
                LFL = longest_file_line(f)

                # create list of number indexes 0:LFL
                fci = range(0, LFL)

                for line in bt.lines(f):
                    tmp_fci = fci[:]
                    for idx in tmp_fci:
                        # current line could be shorter than LFL
                        if idx < len(line):
                            if line[idx] <> ' ':
                                fci.remove(idx)
        
                tmp_fci = fci[:]

                for idx in tmp_fci:
                    if (idx + 1) in fci:
                        fci.remove(idx)

                # list must start with zero to pick first columns when cutting
                if fci[0] <> 0: fci.insert(0, 0)
                # list must end with LFL to pick last columns when cutting
                fci.append(LFL)
                
                fc_indexes[fname] = fci[:]

        return fc_indexes

class FilesColumnsCut:
    """    Cut files to columns based on indexes provided by FileColumnsInfo class.
    
    Multiple passes over big files:
    Columns indexes (where to cut) can be reused from FileColumnsInfo.
    If not reused then they are estimated each time on the fly by FileColumnsInfo invocation.
    If files are big then minimalize need to run routines multiple times over big files
    by running FileColumnsInfo once and supplying (and customizing) indexes to FilesColumnsCut.
    
    Customized indexes:
    Indexes generated by FileColumnsInfo could indicate columns that are not required.
    By supplying customized indexes to FilesColumnsCut user can define which columns are required.
    
    2010-09-12 vp rewrite of previous library
    """
    def __init__(self):
        """ """
        self.fc_indexes = {}                # files column indexes
        self.header_repair_replace = {}     # to repair header damaged by index customization
        self.mode_debug = False
        self.mode_reduce_spaces = False

    def cut(self, filemask=''):
        """ cut data in file to columns
        """
        if filemask == '': 
            print "Error: File mask not defined."
        else:
            for f in sorted(glob.glob(filemask)):
                
                fname = string.split(f, '\x5C')[-1]
                fname = string.split(fname, '.')[0]
                
                # fc_indexes defined by user
                if self.fc_indexes.has_key(fname) == True:
                    fci = self.fc_indexes[fname]
                else: # fc_indexes not defined by user
                    fi = FileColumnsInfo()
                    fci = fi.examine(f)[fname]
                    self.fc_indexes[fname] = fci[:]
    
                if self.mode_debug == True: 
                    idx = "# fc_indexes[\'%s\'] =" % (fname)
                    print '    ', space_fill(idx, 40), fci
                
                of = open(fname + '_csv.#','wb')
                lino = 0
                for line in bt.lines(f):
                    lino += 1
                    # repair header damaged by index customization
                    if lino == 1 and self.header_repair_replace.has_key(fname):
                        of.write(self.header_repair_replace[fname] + n)
                    else:
                        cn = 0
                        cols = cut_by_index(line, fci)
                        #if debugMode == True: print len(cols),
                        for c in cols:
                            cn += 1
                            if self.mode_reduce_spaces == True:
                                c = re.sub(' {2,}', ' ', c)
                            of.write(c + '\t')
                            #print cn, c
                        of.write(n) # next row
                of.close()

if 0:
    import pepe.p_txt.txt_columns as tc

    ### extracting information about files
    # example FileColumnsInfo()

    x = tc.FileColumnsInfo()
    x.mode_debug = True
    x_fci = x.examine(filemask=r'*.TXT_')
    # todo .... automatically fill in fname
    fname = ''
    for k in sorted(x_fci.keys()):
        print "    # fc_indexes[\'%s\'] =" % (fname), x_fci[k]
    """
    banky [0, 4, 14, 52, 74, 84, 92, 101, 106, 128]
    dobropisy [0, 4, 18, 33, 45, 58, 89, 113, 121, 128, 155, 170, 242, 259, 279, 295, 308]
    """

if 0:
    import pepe.p_txt.txt_columns as tc

    ### columns cutting
    # example FilesColumnsCut()

    y = tc.FilesColumnsCut()
    y.mode_debug = True
    #y.mode_reduce_spaces = True

    # banky                 [0, 4, 14, 52, 74, 84, 92, 101, 106, 128]
    y.fc_indexes['banky'] = [0, 4, 14, 52, 74, 84, 92,           128]
    # dobropisy                 [0, 4, 18, 33, 45, 58, 89, 113, 121, 128,      155, 170, 242, 259, 279, 295, 308]
    y.fc_indexes['dobropisy'] = [0, 4, 18, 33, 45, 58, 89, 113, 121, 128, 142, 155, 170, 222, 242, 259, 279, 295, 308]

    y.cut(filemask=r'*.TXT_')

if __name__ == '__main__':
    ''' '''
    #import pepe.p_txt.txt_columns as tc
    """    
    if len(sys.argv) != 2:
        print cutOutColumns.__doc__
    else:
        cutOutColumns(sys.argv[1])
    """
    pass